<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <title>AI 三派厨房大乱斗</title>
  <style>
    :root{--bg:#0f172a;--card:#0b1220;--accent:#ffb86b;--muted:#94a3b8}
    *{box-sizing:border-box;font-family:Inter,Segoe UI,Helvetica,Arial,sans-serif}
    html,body{height:100%;margin:0;background:linear-gradient(180deg,#071021 0%,#0b1220 60%);color:#e6eef8}
    .wrap{max-width:1100px;margin:24px auto;padding:20px}
    header{display:flex;align-items:center;gap:16px}
    h1{margin:0;font-size:22px}
    p.lead{margin:6px 0 18px;color:var(--muted)}
    .board{display:grid;grid-template-columns:320px 1fr;gap:18px}
    .panel{background:linear-gradient(180deg,rgba(255,255,255,0.02),transparent);border:1px solid rgba(255,255,255,0.04);padding:14px;border-radius:12px}
    .chefs{display:flex;flex-direction:column;gap:10px}
    .chef{display:flex;align-items:center;gap:12px;padding:10px;border-radius:10px;background:rgba(255,255,255,0.02)}
    .chef .icon{width:56px;height:56px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:28px}
    .chef .meta{flex:1}
    .chef h3{margin:0;font-size:16px}
    .chef p{margin:4px 0;color:var(--muted);font-size:13px}
    .startbtn{display:inline-block;margin-top:10px;padding:8px 12px;border-radius:8px;background:var(--accent);color:#081024;font-weight:600;cursor:pointer}
    .game-area{min-height:520px}
    .hud{display:flex;gap:10px;align-items:center;margin-bottom:10px}
    .score{background:#071428;padding:8px 12px;border-radius:10px;border:1px solid rgba(255,255,255,0.03)}
    .stage{font-weight:700}
    /* Symbolic game */
    .cook-area{display:flex;flex-direction:column;align-items:center;gap:12px;padding:18px}
    .steak{width:220px;height:140px;border-radius:12px;background:linear-gradient(180deg,#9b5d3a,#6f3b27);display:flex;align-items:center;justify-content:center;font-size:18px;color:#fff}
    .meter{width:260px;height:18px;background:#081426;border-radius:10px;overflow:hidden;border:1px solid rgba(255,255,255,0.03)}
    .meter > i{display:block;height:100%;background:linear-gradient(90deg,#ffd8a8,#ffb86b);width:0}
    .controls{display:flex;gap:8px}
    button{cursor:pointer}
    .muted{color:var(--muted);font-size:13px}
    /* Connectionist - Simon */
    .simon{display:flex;flex-wrap:wrap;gap:10px;width:320px}
    .pad{width:150px;height:150px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:36px;color:#072338;background:#dbeafe;cursor:pointer;user-select:none}
    .pad.disabled{opacity:0.3;pointer-events:none}
    /* Actionist - grid */
    .grid{display:grid;grid-template-columns:repeat(8,36px);grid-auto-rows:36px;gap:6px;padding:10px;background:rgba(255,255,255,0.01);border-radius:10px}
    .cell{width:36px;height:36px;border-radius:6px;background:rgba(255,255,255,0.02);display:flex;align-items:center;justify-content:center}
    .player{background:linear-gradient(180deg,#8be9fd,#56c0d6);}
    .food{background:linear-gradient(180deg,#ffd6e0,#ff9db1);}
    .wall{background:#1b2a3a}
    footer{margin-top:16px;color:var(--muted);font-size:13px}
    .hint{color:#ffd8a8;background:rgba(255,216,168,0.07);padding:8px;border-radius:8px}
    .controls-small{display:flex;gap:8px}
    .small{padding:6px 8px;border-radius:6px;background:#0b1220;border:1px solid rgba(255,255,255,0.03)}
    .center{display:flex;align-items:center;justify-content:center}
    @media(max-width:920px){.board{grid-template-columns:1fr;}.simon{width:100%}.pad{width:48%;height:120px}}
  </style>
</head>
<body>
  <div class="wrap">
    <header>
      <div style="width:56px;height:56px;border-radius:10px;background:linear-gradient(135deg,#ffb86b,#ff7aa2);display:flex;align-items:center;justify-content:center;font-size:28px">🤖</div>
      <div>
        <h1>AI 三派厨房大乱斗</h1>
        <p class="lead">带你用游戏了解：符号主义、连接主义、行为主义。三个小游戏，三种思维。赢得最多分者就是厨房教父！</p>
      </div>
    </header>

    <div class="board">
      <div class="panel">
        <h2 style="margin:0 0 8px">三位大厨</h2>
        <div class="chefs">
          <div class="chef">
            <div class="icon" style="background:linear-gradient(135deg,#ffd8a8,#ffb86b)">📜</div>
            <div class="meta">
              <h3>第一学派 · 符号主义（规则派）</h3>
              <p>擅长精确规则与推理。挑战：精准掌控烹饪时间，命中最佳熟度得分。</p>
            </div>
          </div>

          <div class="chef">
            <div class="icon" style="background:linear-gradient(135deg,#c3f9d6,#66dba6)">🧠</div>
            <div class="meta">
              <h3>第二学派 · 连接主义（仿生派）</h3>
              <p>靠样本和感知学习。挑战：记忆并复现随机味道序列（Simon）。</p>
            </div>
          </div>

          <div class="chef">
            <div class="icon" style="background:linear-gradient(135deg,#cde0ff,#7aa7ff)">🔧</div>
            <div class="meta">
              <h3>第三学派 · 行为主义（行动派）</h3>
              <p>通过行动与反馈优化。挑战：操控机器人收集食材并躲避障碍。</p>
            </div>
          </div>
        </div>

        <div style="margin-top:12px">
          <div class="small muted">玩法：每局包含三轮小游戏（每学派一轮）。每轮得分会累计，最后排名揭晓。</div>
          <div style="margin-top:8px">
            <button id="startAll" class="startbtn">开始一局（3 轮）</button>
            <div class="controls-small" style="margin-top:10px">
              <button id="resetScores" class="small">重置最高分</button>
              <div style="flex:1"></div>
              <div class="muted">版本：教学演示 · 纯前端</div>
            </div>
          </div>
        </div>
      </div>

      <div class="panel game-area">
        <div class="hud">
          <div class="score">阶段：<span id="stage" class="stage">未开始</span></div>
          <div class="score">本局分数：<span id="score">0</span></div>
          <div class="score">最高分：<span id="best">0</span></div>
          <div style="flex:1"></div>
          <div class="muted">提示：玩的时候可以用幽默吐槽三位大厨，学会分别理解三种方法的优劣。</div>
        </div>

        <!-- 符号主义小游戏 -->
        <div id="symbolic" style="display:none">
          <h3>符号主义 · 精准烹饪</h3>
          <div class="cook-area">
            <div class="steak" id="steakText">🥩 牛排（目标：五分熟）</div>
            <div class="meter" title="煎烤进度"><i id="meterBar"></i></div>
            <div class="controls">
              <button id="startCook" class="small">开始煎</button>
              <button id="flip" class="small" disabled>翻面</button>
              <button id="serve" class="small" disabled>出盘（结束）</button>
              <div class="muted">目标：先正面煎 9s，再反面煎 8s（演示时间已缩短为秒）。精准 ±0.8s 得满分。</div>
            </div>
            <div class="hint" id="symHint">计时器会自动推进，翻面与出盘需要点击按钮 — 注意时机。</div>
          </div>
        </div>

        <!-- 连接主义小游戏 -->
        <div id="connectionist" style="display:none">
          <h3>连接主义 · 味道记忆（Simon）</h3>
          <div style="display:flex;gap:18px;align-items:flex-start">
            <div>
              <div class="simon" id="simonPads"></div>
              <div style="margin-top:8px">
                <button id="simonStart" class="small">开始一轮</button>
                <span class="muted" style="margin-left:8px">重复出现的味道序列越长，得分越高。</span>
              </div>
            </div>
            <div style="flex:1">
              <div class="muted">玩法提示：听视觉提示（闪烁）或按键（1-4）来重复序列。没有外部知识——靠记忆和统计学。</div>
              <div style="height:8px"></div>
              <div id="simonInfo" class="muted">当前长度：<span id="simonLen">0</span></div>
            </div>
          </div>
        </div>

        <!-- 行为主义小游戏 -->
        <div id="actionist" style="display:none">
          <h3>行为主义 · 机器人收集</h3>
          <div style="display:flex;gap:14px;align-items:flex-start">
            <div>
              <div class="grid" id="gridArea"></div>
              <div style="margin-top:8px">控制：方向键 ←↑→↓。目标：在 30 次移动内收集尽可能多的食材（粉色）。撞墙会惩罚步数。</div>
            </div>
            <div style="flex:1">
              <div class="muted">环境-反馈式学习：你不断试错来提高效率，类似强化学习。</div>
              <div style="height:8px"></div>
              <div>步数：<span id="steps">0</span> / <span id="maxSteps">30</span></div>
              <div>收集：<span id="collected">0</span></div>
            </div>
          </div>
        </div>

        <div id="endBox" style="display:none;margin-top:12px" class="center">
          <div class="panel" style="max-width:720px">
            <h3 id="resultTitle">本局结果</h3>
            <div id="resultText" style="font-size:14px;color:var(--muted)"></div>
            <div style="margin-top:12px;display:flex;gap:8px">
              <button id="playAgain" class="startbtn">再玩一局</button>
              <button id="share" class="small">把结果复制到剪贴板</button>
              <div style="flex:1"></div>
              <div class="muted">注：游戏为教学目的，时间都被大幅缩短以方便演示。</div>
            </div>
          </div>
        </div>

      </div>
    </div>

    <footer>
      Tips：想让学生更投入？把每位大厨的人设讲成段子，让他们选边站队。玩游戏后问：哪种方法更适合「妈妈味道」这种问题？
    </footer>
  </div>

  <script>
  // 简单游戏管理器
  const startAll = document.getElementById('startAll');
  const stageLabel = document.getElementById('stage');
  const scoreLabel = document.getElementById('score');
  const bestLabel = document.getElementById('best');
  const endBox = document.getElementById('endBox');
  const resultTitle = document.getElementById('resultTitle');
  const resultText = document.getElementById('resultText');
  let totalScore = 0; let best = parseInt(localStorage.getItem('ai_kitchen_best')||'0'); bestLabel.textContent = best;

  function showPanel(id){['symbolic','connectionist','actionist','endBox'].forEach(k=>document.getElementById(k).style.display='none');
    document.getElementById(id).style.display='block';
  }

  // ===== 符号主义（精准烹饪） =====
  const startCook = document.getElementById('startCook');
  const flipBtn = document.getElementById('flip');
  const serveBtn = document.getElementById('serve');
  const meterBar = document.getElementById('meterBar');
  const steakText = document.getElementById('steakText');
  let cookTimer=null, cookT=0, side=0; // side:0正面,1反面
  const TARGET_FRONT = 9.0; const TARGET_BACK = 8.0; // seconds (demo缩短)

  function startSymbolicRound(){
    stageLabel.textContent='符号主义 · 精准烹饪';
    totalScore += 0; scoreLabel.textContent=totalScore;
    showPanel('symbolic');
    // reset
    clearInterval(cookTimer); cookT=0; side=0; meterBar.style.width='0%';
    startCook.disabled=false; flipBtn.disabled=true; serveBtn.disabled=true; steakText.textContent='🥩 牛排（目标：五分熟）';
  }
  startCook.addEventListener('click',()=>{
    startCook.disabled=true; flipBtn.disabled=false; serveBtn.disabled=true; cookT=0; side=0;
    cookTimer = setInterval(()=>{
      cookT += 0.1; // tick
      // progress: for simplicity, map front target to 50% and back to 100%
      let prog = side===0? (cookT / TARGET_FRONT)*50 : (50 + (cookT / TARGET_BACK)*50);
      meterBar.style.width = Math.min(100,prog)+'%';
      if(side===0 && cookT>=TARGET_FRONT*1.5){ // safety stop
        clearInterval(cookTimer); startCook.disabled=false; flipBtn.disabled=true; serveBtn.disabled=false;
      }
    },100);
  });
  flipBtn.addEventListener('click',()=>{
    // record front time
    clearInterval(cookTimer);
    const frontTime = cookT;
    side=1; cookT=0;
    flipBtn.disabled=true; serveBtn.disabled=false; // allow serve after some time
    // update text
    steakText.textContent = '🔄 已翻面，开始反面煎';
    cookTimer = setInterval(()=>{
      cookT += 0.1;
      let prog = 50 + (cookT / TARGET_BACK)*50;
      meterBar.style.width = Math.min(100,prog)+'%';
      if(cookT>=TARGET_BACK*1.5){ clearInterval(cookTimer); }
    },100);
  });
  serveBtn.addEventListener('click',()=>{
    clearInterval(cookTimer);
    // compute score based on closeness to target
    const frontError = Math.abs((side===1?TARGET_FRONT:0) - (side===1?TARGET_FRONT:0)); // unused, compute using stored approach: we need to record frontTime earlier
    // Instead: store front and back via solution: we will track timestamps
    // For simplicity, compute using meter width and cookT
    // Simplify: assume player flipped at time t_flip when side switched; we actually didn't store — let's adjust: store times
  });

  // Let's refactor: store times when flip and serve
  let tFlip=null, tServe=null, cookStart=null;
  startCook.addEventListener('click',()=>{
    startCook.disabled=true; flipBtn.disabled=false; serveBtn.disabled=true; cookT=0; side=0; tFlip=null; tServe=null; cookStart=Date.now();
    clearInterval(cookTimer);
    cookTimer = setInterval(()=>{
      const elapsed=(Date.now()-cookStart)/1000;
      if(side===0){ meterBar.style.width = Math.min(100,(elapsed/TARGET_FRONT)*50)+'%'; }
      else{ const elapsed2=(Date.now()-tFlip)/1000; meterBar.style.width = Math.min(100,50+(elapsed2/TARGET_BACK)*50)+'%'; }
    },80);
  });
  flipBtn.addEventListener('click',()=>{
    if(!cookStart) return;
    tFlip = Date.now(); side=1; flipBtn.disabled=true; serveBtn.disabled=false; steakText.textContent='🔄 已翻面，开始反面煎';
  });
  serveBtn.addEventListener('click',()=>{
    if(!cookStart) return;
    tServe = Date.now(); clearInterval(cookTimer);
    // compute durations
    const front = tFlip? (tFlip - cookStart)/1000 : 0;
    const back = tFlip? (tServe - tFlip)/1000 : (tServe - cookStart)/1000;
    // score: each side gives up to 100, based on gaussian-ish
    function scoreFor(time, target){ const diff=Math.abs(time-target); if(diff<=0.8) return 100; if(diff<=2) return Math.round(100*(1 - (diff-0.8)/3.2)); return Math.max(0,Math.round(100*(1 - diff/6))); }
    const sf = scoreFor(front,TARGET_FRONT); const sb = scoreFor(back,TARGET_BACK);
    const roundScore = Math.round((sf+sb)/2);
    totalScore += roundScore; scoreLabel.textContent = totalScore;
    steakText.textContent = `正面 ${front.toFixed(1)}s ，反面 ${back.toFixed(1)}s → 得分 ${roundScore}`;
    // small delay then next
    setTimeout(()=>{startConnectionistRound();},1600);
  });

  // ===== 连接主义（Simon） =====
  const simonPads = document.getElementById('simonPads');
  const simonStart = document.getElementById('simonStart');
  const simonLenLabel = document.getElementById('simonLen');
  let simonSeq=[], simonPos=0, simonStrict=false;

  function buildSimon(){ const icons=['🍋','🍓','🌶️','🧂']; simonPads.innerHTML=''; icons.forEach((ico,i)=>{
    const d=document.createElement('div'); d.className='pad'; d.textContent=ico; d.dataset.idx=i; d.addEventListener('click',()=>{pressPad(i)});
    simonPads.appendChild(d);
  }); }
  buildSimon();
  function flashPad(i){ const pad = simonPads.children[i]; pad.classList.add('active'); pad.style.transform='scale(1.05)'; setTimeout(()=>{pad.style.transform=''; pad.classList.remove('active')},380); }

  function playSeq(seq,cb){ let i=0; const iv=setInterval(()=>{ flashPad(seq[i]); i++; if(i>=seq.length){ clearInterval(iv); setTimeout(cb,300);} },560); }

  function startConnectionistRound(){
    stageLabel.textContent='连接主义 · 味道记忆'; showPanel('connectionist');
    // init
    simonSeq=[]; simonLenLabel.textContent='0'; simonStart.disabled=false; simonPos=0;
  }
  simonStart.addEventListener('click',()=>{
    simonStart.disabled=true; simonSeq.push(Math.floor(Math.random()*4)); simonLenLabel.textContent=simonSeq.length;
    playSeq(simonSeq,()=>{ enablePlayerSimon(); });
  });
  function enablePlayerSimon(){ simonPos=0; Array.from(simonPads.children).forEach(p=>p.classList.remove('disabled'));
  }
  function disablePlayerSimon(){ Array.from(simonPads.children).forEach(p=>p.classList.add('disabled')) }
  function pressPad(i){ // player input
    flashPad(i);
    if(simonSeq[simonPos]===i){ simonPos++; if(simonPos>=simonSeq.length){ // correct full
        disablePlayerSimon(); // award score depending on length
        const add = simonSeq.length * 80; totalScore += add; scoreLabel.textContent=totalScore;
        // extend sequence and show again a bit later
        setTimeout(()=>{ simonSeq.push(Math.floor(Math.random()*4)); simonLenLabel.textContent=simonSeq.length; playSeq(simonSeq,()=>{ enablePlayerSimon(); }); },700);
    }} else { // wrong
      disablePlayerSimon(); // end this round
      resultText.innerHTML = `在味道记忆环节你记错了（期望 ${simonSeq[simonPos]}），本环节得分结束。`;
      setTimeout(()=>{ startActionistRound(); },900);
    }
  }

  // also arrow keys 1-4
  document.addEventListener('keydown',e=>{
    if(document.getElementById('connectionist').style.display!=='block') return;
    if(['1','2','3','4'].includes(e.key)) pressPad(parseInt(e.key)-1);
  });

  // ===== 行为主义（机器人网格收集） =====
  const gridArea = document.getElementById('gridArea');
  const stepsLabel = document.getElementById('steps');
  const maxStepsLabel = document.getElementById('maxSteps');
  const collectedLabel = document.getElementById('collected');
  let gridW=8, gridH=6, playerPos={x:1,y:1}, foodSet=new Set(), wallSet=new Set(), steps=0, maxSteps=30, collected=0;

  function startActionistRound(){
    stageLabel.textContent='行为主义 · 机器人收集'; showPanel('actionist');
    // build grid
    gridArea.innerHTML=''; gridArea.style.gridTemplateColumns = `repeat(${gridW},36px)`;
    playerPos={x:1,y:1}; steps=0; collected=0; maxSteps=30; stepsLabel.textContent=steps; maxStepsLabel.textContent=maxSteps; collectedLabel.textContent=collected;
    foodSet.clear(); wallSet.clear();
    // random walls and food
    for(let i=0;i<20;i++){ const wx=Math.floor(Math.random()*gridW); const wy=Math.floor(Math.random()*gridH); if((wx===playerPos.x&&wy===playerPos.y)) continue; wallSet.add(`${wx},${wy}`); }
    for(let i=0;i<8;i++){ let fx,fy; do{ fx=Math.floor(Math.random()*gridW); fy=Math.floor(Math.random()*gridH);} while((fx===playerPos.x&&fy===playerPos.y) || wallSet.has(`${fx},${fy}`) || foodSet.has(`${fx},${fy}`)); foodSet.add(`${fx},${fy}`); }
    renderGrid();
  }
  function renderGrid(){ gridArea.innerHTML=''; for(let y=0;y<gridH;y++)for(let x=0;x<gridW;x++){
      const d=document.createElement('div'); d.className='cell'; if(x===playerPos.x && y===playerPos.y) d.classList.add('player'); else if(foodSet.has(`${x},${y}`)) d.classList.add('food'); else if(wallSet.has(`${x},${y}`)) d.classList.add('wall'); d.textContent=''; gridArea.appendChild(d);
    }
  }
  function movePlayer(dx,dy){ if(steps>=maxSteps) return; const nx=playerPos.x+dx, ny=playerPos.y+dy; if(nx<0||ny<0||nx>=gridW||ny>=gridH){ // hit wall boundary -> punish
      steps++; stepsLabel.textContent=steps; // small penalty
      return; }
    if(wallSet.has(`${nx},${ny}`)){ steps++; stepsLabel.textContent=steps; return; }
    playerPos.x=nx; playerPos.y=ny; steps++; stepsLabel.textContent=steps;
    if(foodSet.has(`${nx},${ny}`)){ foodSet.delete(`${nx},${ny}`); collected++; collectedLabel.textContent=collected; totalScore += 120; scoreLabel.textContent=totalScore; }
    renderGrid();
    if(steps>=maxSteps) finishActionRound();
  }
  function finishActionRound(){
    resultText.innerHTML = `本环节结束：收集 ${collected} 个食材，消耗步数 ${steps}。`;
    // small bonus for efficiency
    const bonus = Math.max(0, Math.round((maxSteps-steps)*10)); totalScore += bonus; scoreLabel.textContent = totalScore;
    setTimeout(()=>{ finishGame(); },1000);
  }

  document.addEventListener('keydown',e=>{
    if(document.getElementById('actionist').style.display!=='block') return;
    const keyMap = {'ArrowLeft':[ -1,0],'ArrowRight':[1,0],'ArrowUp':[0,-1],'ArrowDown':[0,1]};
    if(keyMap[e.key]){ e.preventDefault(); movePlayer(...keyMap[e.key]); }
  });

  // ===== Game flow =====
  function finishGame(){
    showPanel('endBox'); endBox.style.display='block'; resultTitle.textContent='一局结束 — 总分：'+totalScore; resultText.innerHTML = `你在三轮挑战中累计得分 <strong>${totalScore}</strong>。`;
    if(totalScore>best){ best=totalScore; localStorage.setItem('ai_kitchen_best',best); bestLabel.textContent=best; resultText.innerHTML += '<br>恭喜！这是新的最高分！'; }
  }

  startAll.addEventListener('click',()=>{
    totalScore=0; scoreLabel.textContent=0; endBox.style.display='none'; startSymbolicRound();
  });
  document.getElementById('playAgain').addEventListener('click',()=>{ totalScore=0; scoreLabel.textContent=0; endBox.style.display='none'; startSymbolicRound(); });
  document.getElementById('share').addEventListener('click',()=>{ navigator.clipboard.writeText(`AI三派厨房大乱斗 分数：${totalScore} （最高 ${best}）`).then(()=>alert('已复制到剪贴板')) });
  document.getElementById('resetScores').addEventListener('click',()=>{ localStorage.removeItem('ai_kitchen_best'); best=0; bestLabel.textContent='0'; alert('已重置最高分'); });

  // Start: show a friendly intro
  stageLabel.textContent='准备中';
  document.addEventListener('DOMContentLoaded',()=>{ stageLabel.textContent='未开始'; });
  </script>
</body>
</html>
